import type { VConsoleOptions } from "core/options.interface";
import type { VSConsolePluginEvent, ViteVSConsoleOptions } from "./types";
import type { Plugin as Plugin_2, ResolvedConfig } from "vite";

const parseVConsoleOptions = (
  config: VConsoleOptions
) => Object.keys(config)
  .map(key => {
    const value = (config as any)[key];
    if (typeof value === "function") {
      if (/^[(f]/.test(value.toString())) {
        return `${key}: ${value},`;
      } else {
        return value;
      }
    }
    return `${key}: ${JSON.stringify(value)}`;
  }).join(',');


const getEventItems = (
  events: VSConsolePluginEvent[],
  id: string
) => {
  return events.map(
    evt => `${id}.on('${evt.eventName}', ${evt.callback})`
  ).join(";");
};

function viteVSConsole<T = Plugin_2>(opt: ViteVSConsoleOptions) {
  const {
    entry,
    enabled = true,
    config = {},
    cacheKey = 'vconsole:enable:id',
    plugin,
    customHide = false
  } = opt;
  let entryPath = Array.isArray(entry) ? entry : [entry];
  let isDev = false;
  if (process.platform === "win32") {
    entryPath = entryPath.map((item) => item.replace(/\\/g, "/"));
  }
  return {
    name: "vite:vconsole",
    enforce: "pre",
    configResolved(resolvedConfig: ResolvedConfig) {
      isDev = resolvedConfig.command === 'serve';
    },
    transform(_source: string, id: string) {
      if (entryPath.includes(id) && enabled) {
        let plugins = "";
        if (plugin && plugin.length) {
          plugins = plugin.map((e) => `
            const ${e.id} = new VConsole.VConsolePlugin('${e.id}', '${e.name}');
            ${getEventItems(e.event, e.id)}
            vConsole.addPlugin(${e.id});`
          ).join(";");
        }

        const code = `/* eslint-disable */
        if (sessionStorage.getItem('${cacheKey}') || ${isDev}) {
          import('vconsole').then(vconsole => {
            var VConsole = vconsole.default;
            var vConsole = new VConsole({ ${parseVConsoleOptions(config)}});
            ${plugins}
            if (${customHide}) {
              vConsole.destroy();
            }
          });
        }
        /* eslint-enable */${_source}`;
        return {
          code,
          map: null
          // support source map
        };
      }

      return {
        code: _source,
        map: null
        // support source map
      };
    }
  } as T;
}

export { viteVSConsole as default, viteVSConsole };
